﻿// Copyright (C) 2014  Patrick Maher

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using Paragon.Geometry;

namespace Paragon.Geometry
{
    public sealed class Octree
    {
        private Node Root { get; set; }
        public int Depth { get; set; }
        private Node _currentNode;
        
        public Octree(int depth)
        {
            Depth = depth;
            Root = new Node();
        }

        public Octree(string sceneFile)
        {
            throw new System.NotImplementedException();
        }

        public void Load(string model)
        {
            throw new System.NotImplementedException();
        }

        public void Insert(int colorData, int address)
        {
            int currentDepth = 0;
            int octant = 0;
            _currentNode = Root;

            while (currentDepth < Depth)
            {
                octant = BvhAddressing.OctantAtDepth(address, currentDepth);

                if (_currentNode.ChildArray == null)
                {
                    _currentNode.ChildArray = new Node[8];
                }

                if (_currentNode.ChildArray[octant] == null)
                {
                    _currentNode.ChildArray[octant] = new Node();
                }

                _currentNode = _currentNode.ChildArray[octant];

                currentDepth++;
            }

            _currentNode.ColorData = colorData;
        }

        public int Read(int address)
        {
            int currentDepth = 0;
            int octant = 0;
            _currentNode = Root;

            while (currentDepth < Depth)
            {
                octant = BvhAddressing.OctantAtDepth(address, currentDepth);

                if (_currentNode.ChildArray == null)
                {
                    return -1;
                }
                if (_currentNode.ChildArray[octant] == null)
                {
                    return -1;
                }
                _currentNode = _currentNode.ChildArray[octant];

                currentDepth++;
            }

            return _currentNode.ColorData;
        }
    }
}